<?php
/**
 * Copyright (c) 2006, PORTALIER Julien
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @package      FeatherPHP
 * @subpackage   Librairies
 * @copyright    Copyright (c) 2006, Julien PORTALIER
 * @link         http://feather.portalier.com
 * @license      http://www.opensource.org/licenses/mit-license.php The MIT License
 */

function __autoload($class)
{
	if (strpos($class, 'Controller'))
	{
		$class = Inflector::underscore(str_replace('Controller', '', $class));
		Loader::load('controllers', $class);
	}
	elseif (strpos($class, 'Model'))
	{
		$class = Inflector::underscore(str_replace('Model', '', $class));
		Loader::load('models', $class);
	}
	elseif (strpos($class, 'Component'))
	{
		$class = Inflector::underscore(str_replace('Component', '', $class));
		Loader::load('controllers'.DS.'components', Inflector::underscore($class));
	}
	elseif (strpos($class, 'Helper'))
	{
		$class = Inflector::underscore(str_replace('Helper', '', $class));
		Loader::load('views'.DS.'helpers', Inflector::underscore($class));
	}
}

class Loader extends Base
{
	private $_models;
	public  $controller;
	public  $view;
	
	function autoload(Controller $controller)
	{
		$this->controller = $controller;
		
		if (Config::$autoloads['database'])
		{
			$this->database();
			require_once FEATHER.'models'.DS.'model.php';
		}
		
		if (!empty(Config::$autoloads['libs']))
			call_user_func_array(array($this, 'libs'), Config::$autoloads['libs']);
		
		if (!empty(Config::$autoloads['components']))
			call_user_func_array(array($this, 'components'), Config::$autoloads['components']);
	}
	
	function controller($class, $url, $action, &$params)
	{
		require_once FEATHER.'controllers'.DS.'controller.php';
		$this->load('controllers', $class, 404);
		$class = Inflector::camelize($class).'Controller';
		
		$controller = new $class($url, $action, $params);
		if (!empty($controller->components))
			call_user_func_array(array($controller->load, 'components'), $controller->components);
		return $controller;
	}
	
	function database()
	{
		$this->load('database', 'database');
	}
	
	function model($class)
	{
		if (!isset($this->_models[$class]))
		{
			$this->load('models', Inflector::underscore($class));
			$this->_models[$class] = new $class($this->controller);
		}
		return $this->_models[$class];
	}
	
	/**
	 * @todo $c *must* be CamelCased!
	 */
	function components()
	{
		$args = func_get_args();
		foreach($args as $c)
		{
			if (!isset($this->controller->$c))
			{
				$this->load('controllers'.DS.'components', Inflector::Underscore($c));
				$class = Inflector::Camelize($c).'Component';
				$this->controller->$c = new $class;
				
				if (method_exists($this->controller->$c, 'startup'))
					$this->controller->$c->startup($this->controller);
			}
			else {
				trigger_error(get_class($this->parent)."::$c has already been declared.", E_USER_WARNING);
			}
		}
	}
	
	function helpers()
	{
		$args = func_get_args();
		if (isset($this->view))
		{
			if (empty($args))
				$args =& Config::$autoloads['helpers'];
			
			foreach($args as $c)
			{
				if (!isset($this->view->$c))
				{
					require_once FEATHER.'views'.DS.'helper.php';
					$this->load('views'.DS.'helpers', $c);
					$class = Inflector::Camelize($c).'Helper';
					$this->view->viewVars[$c] = new $class($this->view);
				}
				else {
					trigger_error(get_class($this->view)."::$c has already been declared.", E_USER_WARNING);
				}
			}
		}
		else
		{
			foreach($args as $c) {
				array_push(Config::$autoloads['helpers'], $c);
			}
		}
	}
	
	function helper($c)
	{
		$this->helpers($c);
		if (isset($this->view))
			return $this->view->viewVars[$c];
	}
	
	static function libs()
	{
		$args = func_get_args();
		foreach($args as $l)
			self::load('libs', $l);
	}
	
	static function vendors()
	{
		$args = func_get_args();
		foreach($args as $c)
		{
			$file = 'vendors'.DS.$c;
			
			if (file_exists(APP.$file))
				require_once APP.$file;
			elseif (file_exists(ROOT.$file))
				require_once ROOT.$file;
			elseif (DEBUG)
				trigger_error(sprintf("There is no such vendor lib '%s'.", $c), E_USER_ERROR);
			else
				Error::show(500);
		}
	}
	
	static function load($path, $c, $errorStatus=500)
	{
		$file = $path.DS."$c.php";
		
		if (file_exists(APP.$file))
			require_once APP.$file;
		elseif (file_exists(FEATHER.$file))
			require_once FEATHER.$file;
		elseif (DEBUG)
			trigger_error(sprintf("There is no such %s '%s'.", Inflector::singularize(basename($path)), Inflector::camelize($c)), E_USER_ERROR);
		else
			Error::show($errorStatus);
	}
}
?>